package elasticsearch

import (
	"bytes"
	"context"
	"encoding/json"
	"github.com/elastic/go-elasticsearch/v7/esapi"
	"goods_srv/goods"
	"goods_srv/models"
	"log"
	"strconv"
	"sync"
)

// 批量添加，同步ES
func SyncGoodsToEs() {
	var goodsList []*models.Goods
	var g models.Goods
	goodsList, _ = g.List()

	//1.从数据库中查询所有的商品
	var wg sync.WaitGroup
	for _, goods := range goodsList {
		wg.Add(1)

		go func(goods *models.Goods) {
			defer wg.Done()

			// Build the request body.
			data, err := json.Marshal(goods)
			if err != nil {
				log.Fatalf("Error marshaling document: %s", err)
			}

			// Set up the request object.
			req := esapi.IndexRequest{
				Index:      "goods",
				DocumentID: strconv.Itoa(int(goods.ID)),
				Body:       bytes.NewReader(data),
				Refresh:    "true",
			}

			//2.将商品数据同步到ES中
			res, err := req.Do(context.Background(), Es)
			if err != nil {
				log.Fatalf("Error getting response: %s", err)
			}
			defer res.Body.Close()

		}(goods)
	}
	wg.Wait()

}

// 搜索
func SearchGoods(keyword string) (goodsList []*goods.GoodsItem) {
	//1.从ES中查询商品
	var buf bytes.Buffer
	//定义查询条件
	var query map[string]interface{}
	if keyword != "" {

		query = map[string]interface{}{
			"query": map[string]interface{}{
				"match": map[string]interface{}{
					"goodsTitle": keyword,
				},
			},
		}

	} else {

		query = map[string]interface{}{
			"query": map[string]interface{}{
				"match_all": map[string]interface{}{},
			},
		}

	}

	//2.将查询数据转为json格式
	if err := json.NewEncoder(&buf).Encode(query); err != nil {
		log.Fatalf("Error encoding query: %s", err)
	}

	//3.执行查询
	res, err := Es.Search(
		Es.Search.WithContext(context.Background()),
		Es.Search.WithIndex("goods"),
		Es.Search.WithBody(&buf),
		Es.Search.WithTrackTotalHits(true),
		Es.Search.WithPretty(),
	)
	if err != nil {
		log.Fatalf("Error getting response: %s", err)
	}
	defer res.Body.Close()

	//打印ES
	//fmt.Println(res)

	var r map[string]interface{}
	if err = json.NewDecoder(res.Body).Decode(&r); err != nil {
		log.Fatalf("Error parsing the response body: %s", err)
	}

	for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) {
		source := hit.(map[string]interface{})["_source"].(map[string]interface{})

		goodsId := source["ID"].(float64)
		goodsTitle := source["goodsTitle"].(string)
		goodsCover := source["goodsCover"].(string)
		goodsPrice := source["goodsPrice"].(float64)

		goodsList = append(goodsList, &goods.GoodsItem{
			GoodsId:    int64(goodsId),
			GoodsTitle: goodsTitle,
			GoodsCover: goodsCover,
			GoodsPrice: float32(goodsPrice),
		})
	}

	return

}
